'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

require('./css/pullrefresh.css');

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * H5高性能下拉刷新组件
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * <PullRefresh onRefresh={this.onRefresh} container={'id'}/>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * 1)H5下拉刷新组件在列表较长时性能上不如native下拉刷新 但是提供了beforePull方法和afterPull方法 这些方法在下拉时都知会执行一次
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * 使用者可以在这些方法里面将不需要的dom隐藏，结束后在显示 最大化优化性能
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                */

var PullRefresh = function (_React$PureComponent) {
    _inherits(PullRefresh, _React$PureComponent);

    function PullRefresh(props) {
        _classCallCheck(this, PullRefresh);

        var _this = _possibleConstructorReturn(this, (PullRefresh.__proto__ || Object.getPrototypeOf(PullRefresh)).call(this, props));

        _this.dragThreshold = _this.props.dragThreshold; // 临界值

        _this.moveCount = _this.props.moveCount; // 位移系数

        _this.dragStart = null; // 开始抓取标志位

        _this.percentage = 0; // 拖动量的百分比

        _this.changeOneTimeFlag = 0; // 修改dom只执行1次标志位

        _this.joinRefreshFlag = null; // 进入下拉刷新状态标志位

        _this.refreshFlag = 0; // 下拉刷新执行是控制页面假死标志位

        _this.state = {};

        _this.touchStart = _this.touchStart.bind(_this);
        _this.touchMove = _this.touchMove.bind(_this);
        _this.touchEnd = _this.touchEnd.bind(_this);
        return _this;
    }
    // static propTypes={
    //     container:React.PropTypes.string, //用于触发滑动事件的容器id，一般为PullRefresh组件的相邻父元素
    //     scrollContainer:React.PropTypes.string, //具有滚动条的容器id，不指定时为document.body，即浏览器窗口；如果是在页面局部容器中下拉刷新则必须指定
    //     dragThreshold:React.PropTypes.number, // 临界值：当拖动多高时触发正在刷新
    //     moveCount:React.PropTypes.number, // 位移系数
    //     beforePull:React.PropTypes.func, // 触发下拉刷新前调用
    //     afterPull:React.PropTypes.number, // 触发下拉刷新后调用  flag：true代表触发了刷新 flag：false代表没有触发下拉刷新只是拉下马又收回去了
    //     onRefresh:React.PropTypes.number // 触发下拉刷新回调 可以用来加载数据
    // };

    _createClass(PullRefresh, [{
        key: 'componentDidMount',
        value: function componentDidMount() {
            var _props = this.props,
                container = _props.container,
                scrollContainer = _props.scrollContainer;


            this.pullIcon = this.refs.pullIcon;

            this.container = document.getElementById(container);

            this.scrollContainer = scrollContainer ? document.getElementById(scrollContainer) : document.body;

            this.bindEvent();
        }
    }, {
        key: 'touchStart',
        value: function touchStart(event) {
            if (this.refreshFlag) {
                event.preventDefault();
                return;
            }

            event = event.touches[0];
            this.dragStart = event.clientY;

            this.container.style.webkitTransition = 'none';
            this.pullIcon.classList.add('none');
        }
    }, {
        key: 'touchMove',
        value: function touchMove(event) {
            if (this.dragStart === null) {
                return;
            }

            if (this.refreshFlag) {
                event.preventDefault();
                return;
            }

            var target = event.touches[0];

            this.percentage = (this.dragStart - target.clientY) / window.screen.height;

            // 当且紧当scrolltop是0且往下滚动时才触发
            if (this.scrollContainer.scrollTop == 0) {
                if (this.percentage < 0) {
                    event.preventDefault();
                    if (!this.changeOneTimeFlag) {

                        this.props.beforePull();
                        this.changeOneTimeFlag = 1;
                    }

                    var translateX = -this.percentage * this.moveCount;

                    this.joinRefreshFlag = true;

                    if (Math.abs(this.percentage) > this.dragThreshold) {

                        this.setState({
                            stateText: '释放刷新'
                        });
                    } else {
                        this.setState({
                            stateText: '下拉刷新'
                        });
                    }

                    if (this.percentage > 0) {

                        this.container.style.webkitTransform = 'translate3d(0,' + translateX + 'px,0)';
                    } else {

                        this.container.style.webkitTransform = 'translate3d(0,' + translateX + 'px,0)';
                    }
                } else {

                    if (this.joinRefreshFlag == null) {
                        this.joinRefreshFlag = false;
                    }
                }
            } else {

                if (this.joinRefreshFlag == null) {
                    this.joinRefreshFlag = false;
                }
            }
        }
    }, {
        key: 'touchEnd',
        value: function touchEnd(event) {
            var _this2 = this;

            if (this.percentage === 0) {
                return;
            }

            if (this.refreshFlag) {
                event.preventDefault();
                return;
            }

            if (Math.abs(this.percentage) > this.dragThreshold && this.joinRefreshFlag) {

                this.props.onRefresh(function () {
                    _this2.setState({
                        stateText: '刷新成功'
                    });
                    _this2.pullIcon.classList.add('none');

                    _this2.container.style.webkitTransform = 'translate3d(0,0,0)';

                    setTimeout(function () {
                        _this2.props.afterPull(true);
                        // 重置标志位
                        _this2.refreshFlag = 0;
                    }, 300);
                });

                this.setState({
                    stateText: '正在刷新..'
                });
                this.pullIcon.classList.remove('none');

                this.container.style.webkitTransition = '330ms';
                this.container.style.webkitTransform = 'translate3d(0,' + 43 + 'px,0)';

                // 进入下拉刷新状态
                this.refreshFlag = 1;
            } else {

                if (this.joinRefreshFlag) {
                    this.refreshFlag = 1;
                    this.container.style.webkitTransition = '330ms';
                    this.container.style.webkitTransform = 'translate3d(0,0,0)';

                    setTimeout(function () {
                        _this2.props.afterPull();
                        // 重置标志位
                        _this2.refreshFlag = 0;
                    }, 300);
                }
            }

            // 重置changeOneTimeFlag
            this.changeOneTimeFlag = 0;

            // 重置joinRefreshFlag
            this.joinRefreshFlag = null;

            // 重置percentage
            this.dragStart = null;

            // 重置percentage
            this.percentage = 0;
        }
    }, {
        key: 'bindEvent',
        value: function bindEvent() {
            var dom = this.container; // 监听touch事件的元素dom
            dom.addEventListener('touchstart', this.touchStart);
            dom.addEventListener('touchmove', this.touchMove);
            dom.addEventListener('touchend', this.touchEnd);
        }
    }, {
        key: 'render',
        value: function render() {
            return React.createElement(
                'div',
                { className: 'pull-down-content' },
                React.createElement('div', { ref: 'pullIcon', className: 'spinner' }),
                React.createElement(
                    'span',
                    null,
                    this.state.stateText
                )
            );
        }
    }]);

    return PullRefresh;
}(React.PureComponent);

PullRefresh.defaultProps = {
    dragThreshold: 0.3,
    moveCount: 200,
    beforePull: function beforePull() {},
    afterPull: function afterPull(flag) {},
    onRefresh: function onRefresh() {}
};
exports.default = PullRefresh;